<html>
<head><meta charset="utf-8"><title>capture clauses · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html">capture clauses</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="230079853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230079853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230079853">(Mar 12 2021 at 18:55)</a>:</h4>
<p>So um I went a little nuts this morning and wrote up an argument in favor of an explicit capture clause annotation on closures:</p>
<p><a href="https://hackmd.io/38jKhUkvSC2pkG1BrI3boQ?edit">https://hackmd.io/38jKhUkvSC2pkG1BrI3boQ?edit</a></p>
<p><em>Something</em> like this is needed to complete the RFC 2229 work. This is more than we need, but I think it's readily implementable and would be really nice to have.</p>



<a name="230079899"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230079899" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230079899">(Mar 12 2021 at 18:55)</a>:</h4>
<p><span class="user-group-mention" data-user-group-id="1977">@T-lang</span> <span aria-label="point up" class="emoji emoji-1f446" role="img" title="point up">:point_up:</span> I'd like to hear loose thoughts, I can open up a project proposal -- in fact, I probably should've done that instead</p>



<a name="230081722"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230081722" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230081722">(Mar 12 2021 at 19:07)</a>:</h4>
<p>Under RFC 2229, is there any way to write "capture the clone of an <code>Arc</code> rather than the original <code>Arc</code>" other than the block-with-let pattern or the proposed <code>#[capture(x.clone())]</code>?</p>



<a name="230081750"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230081750" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230081750">(Mar 12 2021 at 19:07)</a>:</h4>
<p>Also, initial reaction, I feel like allowing expressions like <code>x.clone()</code> there is a rabbit hole.</p>



<a name="230081936"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230081936" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230081936">(Mar 12 2021 at 19:09)</a>:</h4>
<p>I also don't think "prevent capturing anything that isn't listed" is a limitation we need to add to closures. (That's leaving aside other potential motivations.)</p>



<a name="230081985"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230081985" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230081985">(Mar 12 2021 at 19:09)</a>:</h4>
<p>I <em>do</em> find the idea of explicitly saying "I want to capture this by reference" or "I want to capture this by value" interesting, but I wonder how often people will find the automatic detection problematic.</p>



<a name="230082027"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230082027" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230082027">(Mar 12 2021 at 19:09)</a>:</h4>
<p>Other than edition migration, what are the use cases for "I know I <em>could</em> capture less, but I want to capture more"?</p>



<a name="230084909"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230084909" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Cramer <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230084909">(Mar 12 2021 at 19:32)</a>:</h4>
<p>Thanks for the detailed writeup! Overall, I'm not opposed to capture clauses. I'm curious how frequently you imagine users reaching for explicit capture clauses (e.g. is this something that we'd encourage folks to use most/all of the time, or is this an exceptional thing?).</p>
<p>Other unorganized thoughts:</p>
<p><code>x.0.clone()</code> becoming named <code>x</code> will be a source of confusion, and I think I'd prefer <code>x = x.0.clone()</code>, even though it's a slight ergonomic hit. I also think I'm not yet convinced of the relative merit of </p>
<p>I'm not totally sold on the "why this can't be a procedural macro" motivation. Ensuring that no other variables are captured feels like an unnecessary step for users to me, perhaps because I'm used to today's Rust where variable captures are implicit.</p>



<a name="230086159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230086159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Cramer <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230086159">(Mar 12 2021 at 19:42)</a>:</h4>
<p>I do want <code>&lt;ident&gt;.&lt;ident&gt;(..)</code> to bind to the first identifier though, to allow for getters / as_ref/_mut. This relates to a separate concern I have that also applies to the new capture behavior. We currently have a big language pain point around setters/getters not having similar expressivity to field access. This gap stinks, as it imposes severe limits on the usage of structs with private fields. Method access to private fields is useful for guarding against future changes to types (e.g. moving a field behind a Box) and when representing lazily deserialized structures.</p>



<a name="230086289"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230086289" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Cramer <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230086289">(Mar 12 2021 at 19:43)</a>:</h4>
<p>I suppose one way around that is to only offer the <code>&lt;ident&gt; = &lt;expr&gt;</code> syntax, but that quickly becomes quite verbose to the point that an explicit block with <code>let</code> bindings isn't much less inconvenient.</p>



<a name="230105841"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230105841" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230105841">(Mar 12 2021 at 22:04)</a>:</h4>
<p>I do think, other than "prevent anything else from being captured", none of this needs to be at the language level.</p>



<a name="230110450"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230110450" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230110450">(Mar 12 2021 at 22:32)</a>:</h4>
<p>I think this looks a lot better than the <code>{ let x = x.clone(); || ... }</code> idiom (in particular, the default formatting is more convenient), although the attribute makes it clear that this is an afterthought-addition to the language. But it's rare enough that that doesn't bother me so much. For anything other than <code>&amp;x</code> and <code>&amp;mut x</code>, name shadowing should require rebinding like <code>x = x.0</code> for consistency with patterns and struct literals. Something like <code>x.clone()</code> seems just a bit too magical for something in the language itself; it looks more like what a third party crate would do, where you can afford to go nuts with syntax sugar.</p>
<p>As for whether this should be a procedural macro, as a user I don't think it matters, unless this is outside std. I see a possible use for non-<code>..</code> captures but I don't think it should be the default; the main reason I would reach for this feature is to edit a single binding that isn't working right, not ban all the others.</p>



<a name="230113862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230113862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230113862">(Mar 12 2021 at 23:06)</a>:</h4>
<p>Random thought: if it only has explicit captures, it could expose those captures under their names as public fields.</p>
<p>(I'm not yet convinced this is a <em>good</em> idea, but I recall people asking about ways of getting things out of closures, which seems more justifiable if they had to say exactly what was in them anyway.)</p>



<a name="230114188"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230114188" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230114188">(Mar 12 2021 at 23:09)</a>:</h4>
<p>On the naming thing: maybe we can lean on intuition from <code>&amp;self</code>?  So <code>&amp;x</code> and <code>&amp;mut x</code> would be enough, but for anything more complicated it's <code>x = y.z.4</code>.</p>
<p>(Though I'm not really a fan of expressions in attributes, since it makes me think it wants to be "real" syntax.)</p>



<a name="230142584"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230142584" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> isHavvy <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230142584">(Mar 13 2021 at 06:48)</a>:</h4>
<p>One of the things I like in JavaScript is that I can refer to properties on the function object from the function.</p>
<div class="codehilite" data-code-language="JavaScript"><pre><span></span><code><span class="kd">function</span> <span class="nx">make_public_adder</span><span class="p">(</span><span class="nx">addend</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">let</span> <span class="nx">fn</span> <span class="o">=</span> <span class="kd">function</span> <span class="nx">this_fn</span><span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="nx">this_fn</span><span class="p">.</span><span class="nx">a</span> <span class="o">+</span>  <span class="nx">b</span><span class="p">;</span>
    <span class="p">};</span>
    <span class="nx">fn</span><span class="p">.</span><span class="nx">a</span> <span class="o">=</span> <span class="nx">addend</span><span class="p">;</span>
   <span class="k">return</span> <span class="nx">fn</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>



<a name="230143911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230143911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230143911">(Mar 13 2021 at 07:12)</a>:</h4>
<p>I think it would be much better to just stabilize <code>FnOnce&lt;T&gt;</code> so that people can write callable objects rather than adding so much sugar on closure types</p>



<a name="230150922"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230150922" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230150922">(Mar 13 2021 at 09:28)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230081936">said</a>:</p>
<blockquote>
<p>I also don't think "prevent capturing anything that isn't listed" is a limitation we need to add to closures. (That's leaving aside other potential motivations.)</p>
</blockquote>
<p>I should perhaps strengthen the motivation argument there -- in short, I think I would find it surprising to see</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[captures(a, &amp;b)]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>and then find out that the closure also captures <code>c</code>. I can say that I personally have found it annoying sometimes to determine, if there is a long closure, exactly what it captures -- for this reason I personally tend to avoid long closures and prefer methods, so that I can see exactly what state is being passed, but others feel differently.</p>



<a name="230151003"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230151003" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230151003">(Mar 13 2021 at 09:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230105841">said</a>:</p>
<blockquote>
<p>I do think, other than "prevent anything else from being captured", none of this needs to be at the language level.</p>
</blockquote>
<p>Yes, agreed in a technical sense. But I think capture clauses will <em>feel</em> like part of the language however they're implemented, and we do need to ship it by default so we can use it in migration.</p>



<a name="230151073"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230151073" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230151073">(Mar 13 2021 at 09:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="127859">Taylor Cramer</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230084909">said</a>:</p>
<blockquote>
<p><code>x.0.clone()</code> becoming named <code>x</code> will be a source of confusion, and I think I'd prefer <code>x = x.0.clone()</code>, even though it's a slight ergonomic hit. </p>
</blockquote>
<p>Agreed. I wasn't sure about that part of it. I'd be happy to require an explicit name for cases that involve fields. I'm also not sure how important fields are, tbh, but I wanted some way to be "as expressive as the inferred cases", I think (which reminds me, we should include <code>*</code> in the list of places we accept). I should add those notes to the RFC.</p>



<a name="230151086"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230151086" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230151086">(Mar 13 2021 at 09:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230113862">said</a>:</p>
<blockquote>
<p>Random thought: if it only has explicit captures, it could expose those captures under their names as public fields.</p>
</blockquote>
<p>Plausible future extension, perhaps with <code>pub</code> keyword or something.</p>



<a name="230154354"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230154354" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230154354">(Mar 13 2021 at 10:42)</a>:</h4>
<p>OK, I've reworked the draft to include the feedback. I've done the following:</p>
<ul>
<li>We now require an explicit name for captures with fields like <code>x.0.1</code>.</li>
<li>I expanded on the reasoning for requiring a "complete capture list" and gave some examples.</li>
<li>I adjusted the alternatives section to FAQ format and expanded it to include a number of points raised here and the reasons I chose to take the approach I did.</li>
</ul>



<a name="230154362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230154362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230154362">(Mar 13 2021 at 10:42)</a>:</h4>
<p>I also added some more interesting potential future directions that came to me.</p>



<a name="230154387"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230154387" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230154387">(Mar 13 2021 at 10:43)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230143911">said</a>:</p>
<blockquote>
<p>I think it would be much better to just stabilize <code>FnOnce&lt;T&gt;</code> so that people can write callable objects rather than adding so much sugar on closure types</p>
</blockquote>
<p>Can you elaborate a bit more? I don't know exactly what you mean. However, I also think this is unlikely to be something we could fully design and ship in time to be used with the RFC 2229 plans.</p>



<a name="230157770"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230157770" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230157770">(Mar 13 2021 at 11:53)</a>:</h4>
<p>Ohhh I've wanted explicit closure captures for a while!! When programming with unsafe one needs to be very careful with what gets captured, for instance.<br>
I am, however, skeptical of the attribute syntax: std / official attributes have never interacted with runtime code like that. What I mean is while it is possible to write Rust code inside an attribute parameter, only some proc-macros use that (some in a stringified fashion, others in a raw fashion), and code highlifhters handle that wrong.</p>
<p>To me, the better syntax would be to use the <code>move</code> annotation with some optional list of captures. After all, <code>move</code>s and captures mean the same thing, but for the unique "fake binding" sugar for by-ref and by-mut-ref captures. But precisely thanks to the <code>ref</code> and <code>ref mut</code> keywords, that wouldn't impact that often:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span>: <span class="p">(</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">..</span><span class="p">.;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">stuff</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="c1">//or</span>
<span class="kd">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"></span>
</code></pre></div>



<a name="230157974"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230157974" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230157974">(Mar 13 2021 at 11:57)</a>:</h4>
<p>The grammar being that it's either an identifier with optional ref and mut modifiers, or a <code>pat = expr</code> (could be a <code>:</code> to mimic struct sugar, but since that syntax was deemed problematic in hindsight, maybe we shouldn't use that in new places, and favor <code>=</code> in its stead)</p>



<a name="230158229"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230158229" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230158229">(Mar 13 2021 at 12:00)</a>:</h4>
<p>This would also solve the awkwardness of</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">// why should this be mut?</span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
</code></pre></div>
<p>we'd have instead:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="o">..</span><span class="p">.;</span><span class="w"></span>
</code></pre></div>



<a name="230175354"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230175354" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230175354">(Mar 13 2021 at 17:00)</a>:</h4>
<p>I really like the idea of attaching this to the move keyword.</p>



<a name="230175467"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230175467" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230175467">(Mar 13 2021 at 17:02)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> Yes, I'd prefer stable callable objects as well, rather than the closure equivalent of field definitions.</p>



<a name="230175813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230175813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230175813">(Mar 13 2021 at 17:07)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> My point was that if migrations don't need to limit what gets captured (just expand it), that doesn't need a new syntax, since it could use one of the several translations we'd already talked about (drop or a capture macro).</p>



<a name="230175865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230175865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230175865">(Mar 13 2021 at 17:08)</a>:</h4>
<p>This syntax itself may potentially provide great value, and I'd love to see more use cases for it, but I don't think migration is necessarily one of them, given that.</p>



<a name="230176042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230176042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230176042">(Mar 13 2021 at 17:10)</a>:</h4>
<p>I'm starting to see the use case you're getting at for explicitly listing the captures of a closure. That does seem potentially useful, to help wrangle complexity. Rather than tying it to migration and the edition, I'm wondering if we could instead develop that syntax orthogonally to migration, and without having to rush to meet the edition deadline.</p>



<a name="230176711"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230176711" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230176711">(Mar 13 2021 at 17:23)</a>:</h4>
<p>I was actually thinking of making a proc-macro that would try to implement this (using some hygiene hacks to prevent accessing variables that aren't listed). I'd be strongly in favor of having this built-in to the language</p>



<a name="230176878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230176878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230176878">(Mar 13 2021 at 17:26)</a>:</h4>
<p>As a future extension to this, it might be useful to have an allow-by-default lint that that lints against any closures <em>not</em> using the explicit capture syntax. This would allow projects to require that all of their code uses the explicit capture syntax. However, this would essentially be a clippy 'restriction lint' that's part of the main compiler, so I'm not sure that the policy around that is</p>



<a name="230180273"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230180273" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230180273">(Mar 13 2021 at 18:28)</a>:</h4>
<blockquote>
<p>I really like the idea of attaching this to the move keyword.</p>
</blockquote>
<p>I sort of do too. I remember being against <code>keyword(modifiers)</code> when <code>pub(crate)</code> first came out, but on reflection it seems like it solves a variety of syntactic problems, e.g. you could imagine the weird pseudo-lifetime syntax of labeled-break as instead <code>while(label)</code>/<code>break(label)</code>.</p>
<p>although, in any case there's no reason this couldn't start life as an attribute and be expanded into syntax later.</p>



<a name="230180298"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230180298" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230180298">(Mar 13 2021 at 18:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230175354">said</a>:</p>
<blockquote>
<p>I really like the idea of attaching this to the move keyword.</p>
</blockquote>
<p>me, too -- with the <code>=</code> syntax it even supports <code>x = x.clone()</code>.<br>
looks like we're moving closer towards C++ closures then. ;)</p>



<a name="230182200"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230182200" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230182200">(Mar 13 2021 at 19:03)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> That's actually one of the reasons I didn't care for it at first. I don't like C++'s much more manual closures and manual capture syntax.</p>



<a name="230182337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230182337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230182337">(Mar 13 2021 at 19:05)</a>:</h4>
<p>oh sure, keep the automatic mode. but as was said by others above, sometimes this control is what you want.</p>



<a name="230407266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230407266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230407266">(Mar 15 2021 at 19:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116009">nikomatsakis</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230079899">said</a>:</p>
<blockquote>
<p><span class="user-group-mention" data-user-group-id="1977">@T-lang</span> <span aria-label="point up" class="emoji emoji-1f446" role="img" title="point up">:point_up:</span> I'd like to hear loose thoughts, I can open up a project proposal -- in fact, I probably should've done that instead</p>
</blockquote>
<p>I had thought there were (well-established?) issues with putting variables/expressions into attributes, in terms of how that interacts with hygiene and name-resolution. But maybe some of those issues are resolved when the attribute in question is still <em>within the scope</em> of the variable it refers to.</p>



<a name="230408964"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230408964" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230408964">(Mar 15 2021 at 20:02)</a>:</h4>
<p>Also, I’m curious how strong the motivation is to have this expressed as a single explicit list on the lambda expression (or, more generally, each lambda expression, when they are nested.) it would be good if the document considered the alternative of attaching this attribute (or some variation thereof) <em>within</em> the closure body. Something like <code>let c = move || println!("{:?}", (#[capture] x).1);</code> (to capture all of <code>x</code>) vs <code>let c = move || println!("{:?}", #[capture] x.1);</code> (which would capture just the field.</p>



<a name="230412829"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230412829" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230412829">(Mar 15 2021 at 20:26)</a>:</h4>
<p>that's definitely less expressive, since it doesn't cover the <code>clone()</code> examples, although it's probably sufficient for recovering expressivity loss from RFC 2229</p>



<a name="230434931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230434931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230434931">(Mar 15 2021 at 23:01)</a>:</h4>
<p>OK, just catching up here</p>



<a name="230435048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435048">(Mar 15 2021 at 23:02)</a>:</h4>
<p>I'm debating about the move keyword -- my biggest concern is that it doesn't express the implicit capture case. I don't consider <code>move(ref x)</code> to be very nice, because it doesn't behave like <code>ref</code> does in patterns. A <code>ref x </code> pattern gives <code>x</code> a type of <code>&amp;T</code>, but implicit capture in patterns gives <code>x</code> a type of <code>T</code>.</p>



<a name="230435135"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435135" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435135">(Mar 15 2021 at 23:03)</a>:</h4>
<p>I think the line between attributes and regular syntax is pretty squishy; we have tried to hold the line of a 'attributes don't change the "intent" of the code' -- so e.g. you can add <code>#[repr]</code> attributes to a struct, and it may affect the layout, but for the most part you don't need to look at that to understand code using the struct.</p>



<a name="230435153"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435153" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435153">(Mar 15 2021 at 23:03)</a>:</h4>
<p>One could argue the same is true of <code>#[capures]</code>, but it's a bit trickier</p>



<a name="230435204"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435204" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435204">(Mar 15 2021 at 23:04)</a>:</h4>
<p>Anyway I have to run now but later on I'll go over the thread and try to summarize the feedback and update the RFC</p>



<a name="230435221"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435221" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435221">(Mar 15 2021 at 23:04)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> a quite note -- I think that the main problem is that it fails to meet my motivation of 'easily identify what is captured by the closure'</p>



<a name="230435388"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435388" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435388">(Mar 15 2021 at 23:06)</a>:</h4>
<p>I guess that one could say that <code>..</code> in "move" means "implied mode", i.e., we will move these things, and infer the rest</p>



<a name="230435418"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435418" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435418">(Mar 15 2021 at 23:06)</a>:</h4>
<p>after all, my <code>#[captures]</code> annotation is only moves</p>



<a name="230435482"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435482" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435482">(Mar 15 2021 at 23:07)</a>:</h4>
<p>so that the explicit form becomes <code>move(&amp;x) || ..</code>, and the migrations insert <code>move(a, ..) || { use(&amp;a, &amp;b) }</code> (which would mean "capture <code>a</code> by move, and <code>b</code> by shared reference".</p>



<a name="230435492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230435492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230435492">(Mar 15 2021 at 23:07)</a>:</h4>
<p>I don't know, that last example looks awfully misleading to me.</p>



<a name="230437362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230437362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230437362">(Mar 15 2021 at 23:28)</a>:</h4>
<p>I definitely wouldn't want <code>move(ref x)</code>; I think <code>move(&amp;x)</code> logically means "move a reference to x into the closure".</p>



<a name="230440814"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230440814" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230440814">(Mar 16 2021 at 00:06)</a>:</h4>
<p>(I debated about whether to try to generalize my counter proposal to <code>#[capture] (x.clone())</code>, but at that point I think what one is really trying to express is some notion of Aspect Oriented Programming, ie injecting arbitrary code that is meant to be run right before the lambda expression is evaluated. I do think it’s nice to have the definition of the desired expression close to where it will be used (Ie nested within the lambda body) but I suspect it would also be pretty confusing, much like AOP )</p>



<a name="230441153"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230441153" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230441153">(Mar 16 2021 at 00:10)</a>:</h4>
<p>Right the question is what do you consider expressions inside a <code>move()</code> to be. To me they sound a lot like uses, much like passing things to a function as arguments, rather than patterns. So a strong vote for <code>move(&amp;val)</code> from me in context of the <code>move</code> syntax.</p>



<a name="230441441"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230441441" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230441441">(Mar 16 2021 at 00:14)</a>:</h4>
<p>Incidentally I wrote some pretty similar code to what the misleading example looks like <a href="https://gist.github.com/nagisa/544fcb02b9c4da0067cdad1114a0feab">in C++ just now</a>. I think the resulting code is probably somewhat worse in C++ as you can still mutate the referenced value after it has been captured. With rust's unique mutable ownership semantics that would be… less of a problem.</p>



<a name="230451540"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230451540" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230451540">(Mar 16 2021 at 02:34)</a>:</h4>
<p>Also it just occurred to me that in the <code>move(a, b) || use(&amp;a, &amp;b)</code> example there is a serious danger of the reader seeing two function calls separated by OR, if they don't know rust very well and don't realize <code>move</code> is a keyword (or if they just read too quickly). Hopefully they have good syntax highlighting. (That said, I don't really have a better syntax suggestion.)</p>



<a name="230488149"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230488149" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230488149">(Mar 16 2021 at 10:17)</a>:</h4>
<p>well other kinds of grouping tokens could be used. <code>move[...]</code>, <code>move&lt;...&gt;</code>, <code>move{ ... }</code>. I'm quite partial to the last option as an alternative as it looks a lot like struct construction syntax which what closures really are</p>



<a name="230544830"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230544830" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230544830">(Mar 16 2021 at 16:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230451540">said</a>:</p>
<blockquote>
<p>Also it just occurred to me that in the <code>move(a, b) || use(&amp;a, &amp;b)</code> example there is a serious danger of the reader seeing two function calls separated by OR, if they don't know rust very well and don't realize <code>move</code> is a keyword (or if they just read too quickly). Hopefully they have good syntax highlighting. (That said, I don't really have a better syntax suggestion.)</p>
</blockquote>
<p>(this definitely concerned me as soon as I saw that example, because that’s how my brain parses it at first glance. I’d want to explore ways to make it clearer that this is <em>not</em> an or-expression. Not sure what would actually work, though.)</p>



<a name="230545202"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230545202" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230545202">(Mar 16 2021 at 16:25)</a>:</h4>
<p>(of options <span class="user-mention" data-user-id="123586">@nagisa</span> posted, <code>move&lt;…&gt;</code> is one that strikes me as “most different” from an expression. but maybe <code>move { … }</code> would do…)</p>



<a name="230570724"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230570724" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230570724">(Mar 16 2021 at 18:55)</a>:</h4>
<p>So regarding <code>move</code>, I don't mind the grouping sigil used there, I considered brackets given the C++ syntax, and braces given the parallel with the env struct that the closure would have there (but in that case we might go back to using <code>: &lt;expr&gt;</code>?).</p>
<p>And regarding being able to explicitly express the semantics of current implicit by-ref captures, is that a hard requirement? AFAIK, the only place where that occurs is with closures; no user-written code can mimic that, ever. That can be convenient when wanting to be implicit (<em>e.g.</em>, imagine using the <code>with</code> api of <code>LocalKey</code>: one just writes codes without worrying about captures and it Just Works™; this is always the cause for immediately-called closures, and in that case, hiding the technicalities of closure captures makes a lot of sense. But if we are go to using <code>move { a, b }</code> captures, that is, when captures matter, I find the lack of sugar to be quite acceptable, since it consistently mimics pattern destructuring (<em>e.g.</em>, in a hypothetical world, we could have made <code>ref x</code> still bind <code>x</code> to the value, but restricting the access to shared ones, like within a closure capture. In that world, it would make to also feature that capability for explicit closure captures, and the natural syntax for that would have been writing <code>ref &lt;binding&gt;</code>).</p>
<p>To summarize, I do think that this <code>a</code> / <code>b</code> "fields" ought to be written similarly to struct bodies: </p>
<ul>
<li>The mental model here for <code>ref x</code> is that we would be pattern-destructuring against the imaginary struct containing all the available locals at that point. In that regard, writing <code>&amp;x</code> to bind an implicit <code>x</code> by reference would go against the pattern matching habits.</li>
</ul>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">vars</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Vars</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span>: <span class="mi">42</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="k">match</span><span class="w"> </span><span class="n">vars</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Vars</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">ref</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="o">..</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span>: <span class="kp">&amp;</span><span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="p">}}</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">ref</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span>: <span class="kp">&amp;</span><span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="p">};</span><span class="w"></span>
</code></pre></div>
<p>as well as:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">cartesian_product</span><span class="o">&lt;'</span><span class="na">lt</span><span class="p">,</span><span class="w"> </span><span class="n">L</span><span class="w"> </span>: <span class="o">'</span><span class="na">lt</span> <span class="o">+</span><span class="w"> </span><span class="nb">Copy</span><span class="p">,</span><span class="w"> </span><span class="n">R</span><span class="w"> </span>: <span class="o">'</span><span class="na">lt</span> <span class="o">+</span><span class="w"> </span><span class="nb">Copy</span><span class="o">&gt;</span><span class="w"> </span><span class="p">(</span><span class="n">l</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">lt</span> <span class="p">[</span><span class="n">L</span><span class="p">],</span><span class="w"> </span><span class="n">r</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="na">lt</span> <span class="p">[</span><span class="n">R</span><span class="p">])</span><span class="w"></span>
<span class="w">  </span>-&gt; <span class="nc">impl</span><span class="w"> </span><span class="o">'</span><span class="na">lt</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">Iterator</span><span class="o">&lt;</span><span class="n">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">L</span><span class="p">,</span><span class="w"> </span><span class="n">R</span><span class="p">)</span><span class="o">&gt;</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">//                                          consistent syntax</span>
<span class="w">    </span><span class="c1">//                                             vv    vv</span>
<span class="w">    </span><span class="n">l</span><span class="p">.</span><span class="n">iter</span><span class="p">().</span><span class="n">flat_map</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="w"> </span><span class="n">r</span><span class="p">.</span><span class="n">iter</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">|&amp;</span><span class="n">y</span><span class="o">|</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">)))</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>For instance, if somebody that used to write <code>let inc_ref = || Arc::clone(&amp;x)</code> wanted to write the capture explicitly, they would be able to write:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">// Implicit by ref</span>
<span class="kd">let</span><span class="w"> </span><span class="n">inc_ref</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="c1">// Explicit</span>
<span class="kd">let</span><span class="w"> </span><span class="n">inc_ref</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">ref</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="c1">// or</span>
<span class="kd">let</span><span class="w"> </span><span class="n">inc_ref</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span>: <span class="kp">&amp;</span><span class="nc">x</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w"></span>

<span class="c1">// Implicit owned</span>
<span class="kd">let</span><span class="w"> </span><span class="n">inc_ref</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="c1">// Explicit</span>
<span class="kd">let</span><span class="w"> </span><span class="n">inc_ref</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">);</span><span class="w"></span>

<span class="c1">// Implicit owned clone</span>
<span class="kd">let</span><span class="w"> </span><span class="n">inc_ref</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">clone</span><span class="p">();</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="c1">// Explicit</span>
<span class="kd">let</span><span class="w"> </span><span class="n">inc_ref</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span>: <span class="nc">x</span><span class="p">.</span><span class="n">clone</span><span class="p">()</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<ul>
<li>(In a way, current arg-less <code>move</code> would be sugar for <code>move { .. }</code>).</li>
</ul>
<hr>
<p>The other alternative, but which, at the very least, should not be using braced syntax, is to get rid of patterns altogether (since, despite being a core part of the language, it is one very specific to Rust, so many programmers find this paradigm to be confusing and try to reduce it to a minimum (<em>e.g.</em> <a href="https://rust-lang.github.io/rust-clippy/master/#toplevel_ref_arg">it is sometimes linted against</a>, and it's also a reason motivating match ergonomics).</p>
<p>In that case, the syntax ought to be: non-brace group delimiter (I'd even say it ought to be using parenthesis here), and using <code>=</code> instead of <code>:</code>, so as to go as far as possible from struct patterns as possible:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w">  </span><span class="p">(</span><span class="mi">42</span><span class="p">,</span><span class="w"> </span><span class="mi">27</span><span class="p">);</span><span class="w"></span>
<span class="c1">//                +------ values -------+</span>
<span class="c1">//                |                     |</span>
<span class="c1">//                vv                   vv</span>
<span class="kd">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">move</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="n">y</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* … */</span><span class="w"> </span><span class="p">})(</span><span class="o">&amp;</span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="c1">//            ^        ^</span>
<span class="c1">//            +- pats -+</span>
</code></pre></div>
<ul>
<li>With no shorthand, this approach is very similar to the pattern-based one, but for only identifiers being allowed on the lhs of the <code>=</code> sign (no <code>ref x</code>; but I imagine we'd still have <code>mut x</code>?)</li>
</ul>
<p>And then add the (imho, bad) idea that <code>&amp;x</code> would in this one instance of the language be a possible shorthand for a binding by ref: <code>x=&amp;x</code></p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">//            +------- values ------+</span>
<span class="c1">//            |                     |</span>
<span class="c1">//            vv                   vv</span>
<span class="kd">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">move</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="n">y</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* … */</span><span class="w"> </span><span class="p">})(</span><span class="o">&amp;</span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="c1">//             ^   ^</span>
<span class="c1">//             bindings</span>
</code></pre></div>



<a name="230572200"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230572200" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230572200">(Mar 16 2021 at 19:05)</a>:</h4>
<blockquote>
<p>(e.g., in a hypothetical world, we could have made <code>ref x</code> still bind <code>x</code> to the value, but restricting the access to shared ones, like within a closure capture. […]</p>
</blockquote>
<p>what an interesting idea. I wonder how that would have gone over; if it would have made <code>ref</code> “patterns" more palatable… (probably not).</p>



<a name="230573585"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230573585" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230573585">(Mar 16 2021 at 19:15)</a>:</h4>
<blockquote>
<p>And regarding being able to explicitly express the semantics of current implicit by-ref captures, is that a hard requirement?</p>
</blockquote>
<p>The hard requirement is being able to migrate RFC 2229 closures in some way. We could use <code>drop(&amp;a);</code> for that migration, but I would like there to be a syntax for us to move users to that is actually <em>appealing</em>, since in some cases annotations of this kind of will be necessary to get the desired semantics.</p>



<a name="230573648"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230573648" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230573648">(Mar 16 2021 at 19:15)</a>:</h4>
<p>I suppose that we can migrate <code>move</code> closures using <code>move(a, b, c)</code> and non-move closures using <code>drop(&amp;a)</code>, but that seems ungreat.</p>



<a name="230573747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230573747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230573747">(Mar 16 2021 at 19:16)</a>:</h4>
<p>We can support <code>move(..)</code> to mean "move any places used but not explicitly named here"</p>



<a name="230573795"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230573795" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230573795">(Mar 16 2021 at 19:16)</a>:</h4>
<p>We <em>could</em> support <code>move(ref..)</code> or something for the current implicit capture syntax, but I don't love it, for the reasons I've given before (<code>ref</code> calls to mind <code>ref</code> bindings, and they operate differently)</p>



<a name="230573873"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230573873" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230573873">(Mar 16 2021 at 19:16)</a>:</h4>
<p>also, some of the inferred captures may not be refs, they could be mut refs or moves</p>



<a name="230573981"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230573981" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230573981">(Mar 16 2021 at 19:17)</a>:</h4>
<p>We could support <code>move(a, b)</code> and say that we have a lint that warns if you have any variables not cited in the move</p>



<a name="230574146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230574146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230574146">(Mar 16 2021 at 19:18)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116009">nikomatsakis</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230573585">said</a>:</p>
<blockquote>
<p>The hard requirement is being able to migrate RFC 2229 closures in some way. We could use <code>drop(&amp;a);</code> for that migration, but I would like there to be a syntax for us to move users to that is actually <em>appealing</em>, since in some cases annotations of this kind of will be necessary to get the desired semantics.</p>
</blockquote>
<p>maybe we should go for this, I don't know-- we can certainly use <code>drop(&amp;a);</code> for the migration and punt this, but it feels to me like a lost opportunity</p>



<a name="230574280"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230574280" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230574280">(Mar 16 2021 at 19:19)</a>:</h4>
<p>instead of the rather cryptic <code>drop(&amp;a); drop(&amp;b); drop(&amp;c);</code>, <code>let _capture = (&amp;a, &amp;b, &amp;c);</code> would also work, right?</p>



<a name="230575006"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575006" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575006">(Mar 16 2021 at 19:24)</a>:</h4>
<p>I added this FAQ:</p>



<a name="230575012"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575012" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575012">(Mar 16 2021 at 19:24)</a>:</h4>
<h2>Why not use <code>move(CC)</code> as the syntax instead of <code>#[captures(CC)]</code>?</h2>
<p>Syntax like <code>move(a, b, c) || a + b * c</code> has certain advantages:</p>
<ul>
<li>It feels more "built-in" than an attribute.</li>
<li>Something like <code>move(&amp;x)</code> rather clearly expresses that the closure captures a reference to <code>x</code>.</li>
<li>There are no hygiene issues that we have to resolve around the use of attributes.</li>
</ul>
<p>It has some disadvantages as well:</p>
<ul>
<li>It suggests that the closure is a "move" closure, and hence there is no satisfying way to express "and the remaining uses are inferred as normal". This means that <code>move(a, b)</code> cannot be used to migrate non-move closures for RFC 2229 migration; we would have to insert <code>drop(&amp;a);</code> statements explicitly in such code, and all such code in the future would have to be written as move closures.</li>
<li><code>move(a, b) || c</code> looks rather like a function call and the boolean <code>||</code> operator.</li>
</ul>
<p>There are some other alternatives:</p>
<ul>
<li><code>move[a]</code> or <code>move{a}</code> look less like a function call, but they are not consistent visually with <code>pub(super)</code> and the like.</li>
</ul>



<a name="230575039"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575039" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575039">(Mar 16 2021 at 19:24)</a>:</h4>
<p>Regarding the migration, <span class="user-mention" data-user-id="116009">@nikomatsakis</span> is this because it would be done by humans? Because an automatic <code>rustfix</code> would be able to prepend <code>*</code> to all the occurrences of a binding (<code>x</code> -&gt; <code>(*x)</code>):</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">// old:</span>
<span class="kd">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="c1">// new:</span>
<span class="kd">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
</code></pre></div>



<a name="230575090"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575090" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575090">(Mar 16 2021 at 19:25)</a>:</h4>
<p>It is done by rustfix, but that's a lot more code to write</p>



<a name="230575105"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575105" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575105">(Mar 16 2021 at 19:25)</a>:</h4>
<p>I suppose it is plausible</p>



<a name="230575151"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575151" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575151">(Mar 16 2021 at 19:25)</a>:</h4>
<p><code>move(&amp;x) || println!("{}", *x)</code> &lt;-- it would probably be that ;)</p>



<a name="230575188"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575188" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575188">(Mar 16 2021 at 19:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230574280">said</a>:</p>
<blockquote>
<p>instead of the rather cryptic <code>drop(&amp;a); drop(&amp;b); drop(&amp;c);</code>, <code>let _capture = (&amp;a, &amp;b, &amp;c);</code> would also work, right?</p>
</blockquote>
<p>that's true, I consider this also rather cryptic though</p>



<a name="230575220"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575220" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575220">(Mar 16 2021 at 19:25)</a>:</h4>
<p><code>drop((&amp;a, &amp;b, &amp;c));</code> is more compact, but equally cryptic</p>



<a name="230575308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575308">(Mar 16 2021 at 19:26)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116009">nikomatsakis</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230575105">said</a>:</p>
<blockquote>
<p>I suppose it is plausible</p>
</blockquote>
<p>this may be worth considering</p>



<a name="230575366"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575366" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575366">(Mar 16 2021 at 19:26)</a>:</h4>
<p>yeah, all options other than new syntax/attributes are cryptic. but it'd be nice to avoid the word <code>drop</code>. also, clippy will get angry at you for dropping Copy stuff like references.</p>



<a name="230575431"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575431" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575431">(Mar 16 2021 at 19:27)</a>:</h4>
<p>I suppose we could say that rustfix adds <code>drop(&amp;a)</code> and people migrate by hand</p>



<a name="230575447"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575447" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575447">(Mar 16 2021 at 19:27)</a>:</h4>
<p>also</p>



<a name="230575463"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575463" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575463">(Mar 16 2021 at 19:27)</a>:</h4>
<p>(fwiw, I personally find <code>let _captures =</code> to be a bit more readable than <code>drop</code>)</p>



<a name="230575466"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575466" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575466">(Mar 16 2021 at 19:27)</a>:</h4>
<p>like, the <code>move(&amp;a)</code> is the <em>recommended</em> way to do it, but...</p>



<a name="230575503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575503">(Mar 16 2021 at 19:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232018">Daniel Henry-Mantilla</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230575463">said</a>:</p>
<blockquote>
<p>(fwiw, I personally find <code>let _captures =</code> to be a bit more readable than <code>drop</code>)</p>
</blockquote>
<p>it is, it's just not good enough (to me) to be the "official' way to do this</p>



<a name="230575532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575532">(Mar 16 2021 at 19:27)</a>:</h4>
<p>and i think we want something to tell authors of new code when they're like "how can I force it to capture all of <code>a</code>"</p>



<a name="230575534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575534">(Mar 16 2021 at 19:27)</a>:</h4>
<p>That's fair</p>



<a name="230575550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575550">(Mar 16 2021 at 19:27)</a>:</h4>
<p>I'd rather that not be <code>let _capture = &amp;a</code></p>



<a name="230575611"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575611" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575611">(Mar 16 2021 at 19:28)</a>:</h4>
<p>the "cliff" to <code>move</code> is a bit unfortunate but maybe ok</p>



<a name="230575688"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575688" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575688">(Mar 16 2021 at 19:28)</a>:</h4>
<p>(sure. but <code>let _ = &amp;a;</code> is still better than <code>drop(&amp;a);</code> which keeps coming up as an example)</p>



<a name="230575806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575806">(Mar 16 2021 at 19:29)</a>:</h4>
<p>looking forward to explicit capture syntax</p>



<a name="230575928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575928">(Mar 16 2021 at 19:30)</a>:</h4>
<p>I suppose <code>let _ = &amp;a</code> actually does work</p>



<a name="230575996"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230575996" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230575996">(Mar 16 2021 at 19:30)</a>:</h4>
<p>I thought it didn't, beacuse of the "special semantics" of <code>let _ = &lt;place&gt;</code></p>



<a name="230576003"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576003" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576003">(Mar 16 2021 at 19:30)</a>:</h4>
<p>but <code>&amp;a</code> is not a place</p>



<a name="230576015"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576015" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576015">(Mar 16 2021 at 19:30)</a>:</h4>
<p>regardless, the point stands :)</p>



<a name="230576088"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576088" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576088">(Mar 16 2021 at 19:31)</a>:</h4>
<p>I do agree <code>let _ = (&amp;a, &amp;b, ... &amp;z);</code> is a better migration</p>



<a name="230576155"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576155" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576155">(Mar 16 2021 at 19:31)</a>:</h4>
<p>I just don't love it as the official answer for what to do</p>



<a name="230576212"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576212" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576212">(Mar 16 2021 at 19:31)</a>:</h4>
<p>ballpark estimate of how common you expect this to be needed? 1% of the time, more, less? using an attribute as placeholder syntax isn't a bad idea if it's a particularly rare case, as long as you're okay with attributes referencing runtime things</p>



<a name="230576562"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576562" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576562">(Mar 16 2021 at 19:33)</a>:</h4>
<p>Fairly uncommon</p>



<a name="230576643"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576643" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576643">(Mar 16 2021 at 19:34)</a>:</h4>
<p>I think if it were <em>just</em> rfc2229 I wouldn't worry <em>that</em> much, though I'm not <em>thrilled</em>, but I think that if you add up the various motivations, you get a stronger case.</p>



<a name="230576656"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230576656" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230576656">(Mar 16 2021 at 19:34)</a>:</h4>
<p>I'm going to weigh the <code>move</code> syntax idea a bit :)</p>



<a name="230577214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230577214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230577214">(Mar 16 2021 at 19:37)</a>:</h4>
<p>Potentially stupid suggestion I just came up with: if we are not using <code>ref x</code> but <code>&amp;x</code>, we no longer have to follow pattern logic <em>at all</em>, so what about <code>move(&amp;x)</code> captures by reference but binds to the type of <code>x</code>?</p>



<a name="230577365"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230577365" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230577365">(Mar 16 2021 at 19:38)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">get_ft</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">move</span><span class="p">[</span><span class="o">&amp;</span><span class="n">x</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
</code></pre></div>



<a name="230577632"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230577632" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230577632">(Mar 16 2021 at 19:40)</a>:</h4>
<p><a href="/user_uploads/4715/gQM1nJBWF-ZfuXgC2EFnF9Po/image.png">image.png</a></p>
<div class="message_inline_image"><a href="/user_uploads/4715/gQM1nJBWF-ZfuXgC2EFnF9Po/image.png" title="image.png"><img src="/user_uploads/4715/gQM1nJBWF-ZfuXgC2EFnF9Po/image.png"></a></div>



<a name="230577822"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230577822" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230577822">(Mar 16 2021 at 19:41)</a>:</h4>
<p>not <code>ref x</code>, but still <code>mut x</code>?</p>



<a name="230578472"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230578472" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230578472">(Mar 16 2021 at 19:45)</a>:</h4>
<p><span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span> Allowing the <code>move[mut x]</code> shorthand would be convenient but inconsistent with the <code>&amp;x</code> suggestion I just made.<br>
I guess the <code>mut</code> case ought to need the full syntax (which does not seem too bad to me):</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">move</span><span class="p">[</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* … */</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="230581671"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230581671" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230581671">(Mar 16 2021 at 20:04)</a>:</h4>
<p>then you could also do <code>move[mut x = 0] || { x += 1; x }</code> without needing to declare an <code>x</code> outside of it at all. but at this point <code>move</code> is a bit of a weird word to use here.</p>



<a name="230582477"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230582477" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230582477">(Mar 16 2021 at 20:09)</a>:</h4>
<p>what about <code>move</code> inside the closure? <code>|| { move x; ... }</code></p>



<a name="230582778"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230582778" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230582778">(Mar 16 2021 at 20:11)</a>:</h4>
<p>we've had other discussions about <code>move</code> in expressions, not directly related to closures</p>



<a name="230582903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230582903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230582903">(Mar 16 2021 at 20:11)</a>:</h4>
<p><a href="#narrow/stream/122651-general/topic/In.20a.20closure.2C.20how.20do.20I.20move.20some.20things.20but.20not.20others.3F">https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/In.20a.20closure.2C.20how.20do.20I.20move.20some.20things.20but.20not.20others.3F</a></p>



<a name="230583126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230583126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230583126">(Mar 16 2021 at 20:13)</a>:</h4>
<p>well I guess that did start about closures, but the <code>.move</code> idea has potential traction regardless, IMO</p>



<a name="230583292"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230583292" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230583292">(Mar 16 2021 at 20:14)</a>:</h4>
<p>here's another thread on that:</p>



<a name="230583295"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230583295" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230583295">(Mar 16 2021 at 20:14)</a>:</h4>
<p><a href="#narrow/stream/213817-t-lang/topic/Spitballing.3A.20a.20.60move(x).60.20expression.3F">https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Spitballing.3A.20a.20.60move(x).60.20expression.3F</a></p>



<a name="230584123"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230584123" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230584123">(Mar 16 2021 at 20:19)</a>:</h4>
<p><span class="user-mention silent" data-user-id="310399">Mara</span> <a href="#narrow/stream/213817-t-lang/topic/capture.20clauses/near/230581671">said</a>:</p>
<blockquote>
<p>at this point <code>move</code> is a bit of a weird word to use here.</p>
</blockquote>
<p>Interesting, I personally find it very intuitive: we are moving a value (<code>0</code>) as <code>x</code> into the closure('s captures). The one a bit weird is my suggested semantics for <code>move(&amp;x)</code>, since it would be kind of an oxymoron <span aria-label="sweat smile" class="emoji emoji-1f605" role="img" title="sweat smile">:sweat_smile:</span>  (in that regard, <code>#[captures]</code> has at least the advantage of being a bit more readable)</p>



<a name="230584551"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/capture%20clauses/near/230584551" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/capture.20clauses.html#230584551">(Mar 16 2021 at 20:22)</a>:</h4>
<p>yes, that thread on <code>move</code> expressions seems pretty relevant here, although if the semantics are chosen such that <code>let y = x.move</code> invalidates <code>x</code> even if <code>x</code> is <code>Copy</code>, then for the purposes here you might sometimes need to do <code>(&amp;x).move</code> (or <code>move &amp;x</code>), which I suppose is no worse than the <code>drop</code> or <code>let _captures</code> forms above</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>